home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Communication
/
NewsBase
/
Source
/
TransparentWindow.m
< prev
next >
Wrap
Text File
|
1993-01-12
|
9KB
|
306 lines
// TransparentWindow.m
// By Jayson Adams, NeXT Developer Support Team
// You may freely copy, distribute and reuse the code in this example.
// NeXT disclaims any warranty of any kind, expressed or implied, as to its
// fitness for any particular use.
// modified by Miyai, ISR 1992.7.28
#import <math.h>
#import <string.h>
#import <dpsclient/wraps.h>
#import <appkit/publicWraps.h>
#import <appkit/NXImage.h>
#import <appkit/Window.h>
#import <appkit/Application.h>
#import "pswraps.h"
#import "AcceptWindow.h"
#import "Animator.h"
#import "TransparentWindow.h"
#import "errdebug.h"
#define NOWINDOW 0
@implementation TransparentWindow
- initForImage:anImage at:(NXPoint *)windowOrigin forView:anObject
{
NXRect windowFrame;
NXPoint origin = {0.0, 0.0};
/*
* create an offscreen window with the image (for use in our pswrap routines)
*/
[anImage getSize:&windowSize];
windowFrame.origin.x = windowFrame.origin.y = 0.0;
windowFrame.size = windowSize;
image = [[Window alloc] initContent:&windowFrame
style:NX_PLAINSTYLE
backing:NX_RETAINED
buttonMask:0
defer:NO];
/* copy the image to our new window */
[[image contentView] lockFocus];
[anImage composite:NX_COPY toPoint:&origin];
[[image contentView] unlockFocus];
/* save the object that created us */
source = anObject;
// iIconImage = [anObject image];
iIconImage = anImage;
if([anObject respondsTo:@selector(title)]) {
strncpy (iTitle, [anObject title], sizeof(iTitle)-1);
}
/*
* create an animator to move our transparent window back to its origin if
* the user lets go of the window over something that won't accept it; we'll
* create it now so there's no delay when we really need it
*/
animator = [[Animator alloc] initChronon:(1.0 / 40.0)
adaptation:0.0
target:self
action:@selector(animateBack:)
autoStart:NO
eventMask:0];
iDefaultAccepted = NO;
return self;
}
- free
{
[image free];
[animator free];
return [super free];
}
- imageWindow
{
return image;
}
- image
{
return iIconImage;
}
- source
{
return source;
}
- (const char *)title
{
return (const char *)iTitle;
}
- dragFromMouseDown:(NXPoint *)startingPoint mouseOffset:(NXPoint *)offset
{
int mouseUp = 0, windowUnderImage, windowUnderMouseChanged = 0,
previousWindowUnderMouseChanged = 0;
unsigned int windowNum;
// BOOL accepted = NO;
BOOL accepted;
float deltaX, deltaY, distance;
// set default for accepted
// iDefaultAccepted : NO: for IFolderTransparentWindow
// YES: for TransparentWindow
accepted = iDefaultAccepted;
/* disable the wait cursor for our dragging loop */
PSsetwaitcursorenabled(NO);
/* get the image's gstate for our dragWindow pswrap */
imageGstate = [image gState];
currentPoint = stoppingPoint = *startingPoint;
/* set everything up for the drag loop */
initDrag(currentPoint.x, currentPoint.y, offset->x, offset->y,
windowSize.width, windowSize.height, &iWindow, &bgWindow,
&niWindow, &igstate, &bggstate, &nigstate, &gWindow, &ggstate);
while (!mouseUp) {
/* call the pswrap that moves the transparent window */
dragWindow(iWindow, niWindow, gWindow, windowUnderMouseChanged,
previousWindowUnderMouseChanged, igstate, bggstate,
nigstate, imageGstate, ggstate, currentPoint.x,
currentPoint.y, offset->x, offset->y, windowSize.width,
windowSize.height, &mouseUp, &windowUnderImage,
&(currentPoint.x), &(currentPoint.y));
[self checkForAcceptWindow:windowUnderImage
atPoint:¤tPoint
:&windowUnderMouseChanged
:&previousWindowUnderMouseChanged];
}
/*
* flush window's because checkForAcceptWindow might've caused windows to
* change and the user may have let go of the mouse, making mouseUp true and
* preventing dragWindow from getting called (which does the flushWindows
* normally)
*/
if (windowUnderMouseChanged) {
NXConvertGlobalToWinNum(windowUnderMouseChanged, &windowNum);
[[NXApp findWindow:windowNum] flushWindow];
}
DBG(1,fprintf(stderr," previousWindowUnderMouse = %d\n",
(int)previousWindowUnderMouse));
/*
* if there was a window under the mouse point, flush it for the reasons
* above, plus tell it the user dropped the image on it
*/
if (previousWindowUnderMouse) {
if (previousWindowUnderMouseChanged) {
[previousWindowUnderMouse flushWindow];
}
// accepted = [previousWindowUnderMouse windowDropped:¤tPoint
// fromSource:source];
accepted = [previousWindowUnderMouse windowDropped:¤tPoint
fromSource:self];
}
/* turn the wait cursor back on */
PSsetwaitcursorenabled(YES);
/*
* if the user didn't drop the window over an accepting window, or the
* window didn't accept it, animate the transparent window back to its origin
*/
if (!accepted) {
deltaX = currentPoint.x - startingPoint->x;
deltaY = currentPoint.y - startingPoint->y;
if (deltaX && deltaY) {
distance = sqrt(deltaX * deltaX + deltaY * deltaY);
frames = ceil(40.0 * distance / 5000.0);
if (frames == 1) {
/* make an exception for windows close to their origin */
frames = ceil(40.0 * distance / 1400.0);
}
increment.x = deltaX / frames;
increment.y = deltaY / frames;
/* we need to remember the mouse offset */
mouseOffset = *offset;
[animator startEntry];
[self preambleForAccepted:accepted]; //accepted = NO;
return self;
}
}
/* destroy the windows and gstates used to drag the TransparentWindow */
cleanup(iWindow, bgWindow, niWindow, gWindow, igstate, bggstate, nigstate,
ggstate);
return [self free];
}
- animateBack:sender
{
/* compute the transparent window's new location */
currentPoint.x -= increment.x;
currentPoint.y -= increment.y;
/* see if new location is close enough to the final position */
if ((increment.x > 0 && (currentPoint.x < stoppingPoint.x + 3.0)) ||
(increment.x < 0 && (currentPoint.x > stoppingPoint.x - 3.0))) {
currentPoint.x = stoppingPoint.x;
}
if ((increment.y > 0 && (currentPoint.y < stoppingPoint.y + 3.0)) ||
(increment.y < 0 && (currentPoint.y > stoppingPoint.y + 3.0))) {
currentPoint.y = stoppingPoint.y;
}
/* move it there */
miniDragWindow(iWindow, niWindow, gWindow, igstate, bggstate, nigstate,
imageGstate, ggstate, currentPoint.x, currentPoint.y,
mouseOffset.x, mouseOffset.y, windowSize.width,
windowSize.height);
/* count down the number of frames */
if (--frames) {
return self;
}
/* all done */
[animator stopEntry];
cleanup(iWindow, bgWindow, niWindow, gWindow, igstate, bggstate, nigstate,
ggstate);
return [self free];
}
- checkForAcceptWindow:(int)windowNumUnderMouse atPoint:(NXPoint *)point
:(int *)windowUnderMouseChanged :(int *)previousWindowUnderMouseChanged
{
unsigned int windowNum;
id windowUnderMouse = NOWINDOW;
*windowUnderMouseChanged = 0;
*previousWindowUnderMouseChanged = 0;
/* find the window object under the mouse point */
if (windowNumUnderMouse) {
NXConvertGlobalToWinNum(windowNumUnderMouse, &windowNum);
windowUnderMouse = [NXApp findWindow:windowNum];
if (![windowUnderMouse
respondsTo:@selector(windowEntered:fromSource:)]) {
windowUnderMouse = NOWINDOW;
windowNumUnderMouse = 0;
}
}
/*
* tell the window previously under the mouse (if different) that the image
* exited
*/
if (windowUnderMouse != previousWindowUnderMouse &&
previousWindowUnderMouse != NOWINDOW) {
// if ([previousWindowUnderMouse windowExited:source]) {
if ([previousWindowUnderMouse windowExited:self]) {
*previousWindowUnderMouseChanged = previousWindowNumUnderMouse;
}
}
/* tell the window under the mouse (if it exists) that the image entered */
if (windowUnderMouse != NOWINDOW) {
// if ([windowUnderMouse windowEntered:point fromSource:source]) {
if ([windowUnderMouse windowEntered:point fromSource:self]) {
*windowUnderMouseChanged = windowNumUnderMouse;
}
}
previousWindowUnderMouse = windowUnderMouse;
previousWindowNumUnderMouse = windowNumUnderMouse;
return self;
}
- (BOOL)defaultAccepted
{
return iDefaultAccepted;
}
- preambleForAccepted:(BOOL)flag
{
// should be overriden by its subclass
return self;
}
@end